﻿using CPPEI.Coolzon.Metadata;
using CPPEI.Coolzon.UI.Script;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace CPPEI.Coolzon.UI
{
    public partial class Part
    {
        /// <summary>
        /// 控件的全称
        /// </summary>
        public string XFullName { get; set; }

        private string _xCaption;

        protected bool NeedUpdateLayout = false;
        #region XProperties

        public string XCaption
        {
            get
            {
                return _xCaption;
            }
            set
            {
                if (!string.Equals(_xCaption, value))
                {
                    _xCaption = value;
                    RaisePropertyChanged("XCaption");
                }
            }
        }

        /// <summary>
        /// 显示条件，这里定义了显示的表达式，如果表达式为空则显示，不为空返回的值为true显示，false不显示
        /// </summary>        
        [Category("脚本")]
        [DisplayName("显示条件")]
        [Description("DisplayCondition")]
        [Editor(typeof(XProperty.Editors.XStringEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Script, "DisplayCondition", "显示条件")]
        public string XDisplayCondition
        {
            get
            {
                return (string)GetValue(XDisplayConditionProperty);
            }
            set
            {
                SetValue(XDisplayConditionProperty, value);
            }
        }
        [Category("Layout")]
        [DisplayName("左部距离")]
        [Description("Left")]
        [Editor(typeof(XProperty.Editors.XDoubleEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Layout, "Left", "左部距离")]
        public double XLeft
        {
            get
            {
                return (double)GetValue(XLeftProperty);
            }
            set
            {
                SetValue(XLeftProperty, value);
            }
        }

        [Category("Layout")]
        [DisplayName("上部距离")]
        [Description("Top")]
        [Editor(typeof(XProperty.Editors.XDoubleEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Layout, "Top", "上部距离")]
        public double XTop
        {
            get
            {
                return (double)GetValue(XTopProperty);
            }
            set
            {
                SetValue(XTopProperty, value);
            }
        }

        [Category("Layout")]
        [DisplayName("高度")]
        [Description("Height")]
        [Editor(typeof(XProperty.Editors.XDoubleEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Layout, "Height", "高度")]
        public double XHeight
        {
            get
            {
                return (double)GetValue(XHeightProperty);
            }
            set
            {
                SetValue(XHeightProperty, value);
            }
        }

        [Category("Layout")]
        [DisplayName("宽度")]
        [Description("Width")]
        [Editor(typeof(XProperty.Editors.XDoubleEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Layout, "Width", "宽度")]
        public double XWidth
        {
            get
            {
                return (double)GetValue(XWidthProperty);
            }
            set
            {
                SetValue(XWidthProperty, value);
            }
        }

        /// <summary>
        /// 背景颜色
        /// </summary>
        [Category("Appearance")]
        [DisplayName("背景颜色")]
        [Description("Background")]
        [Editor(typeof(XProperty.Editors.XBrushEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Appearance, "Background", "背景颜色")]
        public BrushEx XBackground
        {
            get
            {
                return (BrushEx)GetValue(XBackgroundProperty);
            }
            set
            {
                SetValue(XBackgroundProperty, value);
            }
        }

        [Category("Appearance")]
        [DisplayName("前景颜色")]
        [Description("Foreground")]
        [Editor(typeof(XProperty.Editors.XBrushEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Appearance, "Foreground", "前景颜色")]
        public BrushEx XForeground
        {
            get
            {
                return (BrushEx)GetValue(XForegroundProperty);
            }
            set
            {
                SetValue(XForegroundProperty, value);
            }
        }

        /// <summary>
        /// 背景图片
        /// </summary>
        [Category("Brush")]
        [DisplayName("背景图片")]
        [Description("BackgroundImage")]
        [Editor(typeof(XProperty.Editors.XImageSourceFileEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Brush, "BackgroundImage", "背景图片", true, false)]
        public ImageSourceFile XBackgroundImage
        {
            get
            {
                return (ImageSourceFile)GetValue(XBackgroundImageProperty);
            }
            set
            {
                if(value !=null)
                {
                    this.XBackground = new BrushEx(new ImageBrush(value.ImageSource));
                }
                SetValue(XBackgroundImageProperty, value);
            }
        }

        /// <summary>
        /// 边框颜色
        /// </summary>
        [Category("Appearance")]
        [DisplayName("边框颜色")]
        [Description("BorderBrush")]
        [Editor(typeof(XProperty.Editors.XBrushEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Appearance, "BorderBrush", "边框颜色")]
        public BrushEx XBorderBrush
        {
            get
            {
                return (BrushEx)GetValue(XBorderBrushProperty);
            }
            set
            {
                SetValue(XBorderBrushProperty, value);
            }
        }

        /// <summary>
        /// 边框大小
        /// </summary>
        [Category("Appearance")]
        [DisplayName("边框大小")]
        [Description("BorderThickness")]
        [Editor(typeof(XProperty.Editors.XThicknessEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Appearance, "BorderThickness", "边框大小")]
        public Thickness XBorderThickness
        {
            get
            {
                return (Thickness)GetValue(XBorderThicknessProperty);
            }
            set
            {
                SetValue(XBorderThicknessProperty, value);
            }
        }

        [Category("Layout")]
        [DisplayName("外边距")]
        [Description("Margin")]
        [Editor(typeof(XProperty.Editors.XThicknessEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Layout, "Margin", "外边距", true, true)]
        public Thickness XMargin
        {
            get
            {
                return (Thickness)GetValue(XMarginProperty);
            }
            set
            {
                SetValue(XMarginProperty, value);
            }
        }

        [Category("Layout")]
        [DisplayName("内边距")]
        [Description("Padding")]
        [Editor(typeof(XProperty.Editors.XThicknessEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Layout, "Padding", "内边距")]
        public Thickness XPadding
        {
            get
            {
                return (Thickness)GetValue(XPaddingProperty);
            }
            set
            {
                SetValue(XPaddingProperty, value);
            }
        }

        private bool _isVisible = true;
        /// <summary>
        /// 
        /// </summary>
        [Category("Appearance")]
        [DisplayName("是否可见")]
        [Description("IsVisible")]
        [Editor(typeof(XProperty.Editors.XBooleanEditor), typeof(XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Appearance, "IsVisible", "是否可见", true)]
        public bool XIsVisible
        {
            get
            {
                return (bool)GetValue(XIsVisibleProperty);
            }
            set
            {
                SetValue(XIsVisibleProperty, value);
            }
        }
        #endregion

        #region dependency property
        public static DependencyProperty XDisplayConditionProperty = DependencyProperty.Register("XDisplayCondition",
            typeof(string),
            typeof(Part),
            new PropertyMetadata(default(string), XDisplayConditionPropertyChangedCallback));

        public static DependencyProperty XLeftProperty = DependencyProperty.Register("XLeft",
            typeof(double),
            typeof(Part),
            new PropertyMetadata(default(double), XLeftPropertyChangedCallback));

        public static DependencyProperty XTopProperty = DependencyProperty.Register("XTop",
            typeof(double),
            typeof(Part),
            new PropertyMetadata(default(double), XTopPropertyChangedCallback));

        public static DependencyProperty XWidthProperty = DependencyProperty.Register("XWidth",
            typeof(double),
            typeof(Part),
            new PropertyMetadata(default(double), XWidthPropertyChangedCallback));

        public static DependencyProperty XHeightProperty = DependencyProperty.Register("XHeight",
            typeof(double),
            typeof(Part),
            new PropertyMetadata(default(double), XHeightPropertyChangedCallback));

        public static DependencyProperty XBackgroundProperty = DependencyProperty.Register("XBackground",
            typeof(BrushEx),
            typeof(Part),
            new PropertyMetadata(null, XPropertyChangedCallback));

        public static DependencyProperty XForegroundProperty = DependencyProperty.Register("XForeground",
            typeof(BrushEx),
            typeof(Part),
            new PropertyMetadata(null, XPropertyChangedCallback));

        public static DependencyProperty XBackgroundImageProperty = DependencyProperty.Register("XBackgroundImage",
            typeof(ImageSourceFile),
            typeof(Part),
            new PropertyMetadata(null, XPropertyChangedCallback));

        public static DependencyProperty ToolbarContentProperty = DependencyProperty.Register("ToolbarContent",
            typeof(object),
            typeof(Part),
            null);

        public static DependencyProperty XBorderBrushProperty = DependencyProperty.Register("XBorderBrush",
            typeof(BrushEx),
            typeof(Part),
            new PropertyMetadata(null, XBorderBrushPropertyChangedCallback));

        public static DependencyProperty XBorderThicknessProperty = DependencyProperty.Register("XBorderThickness",
            typeof(Thickness),
            typeof(Part),
            new PropertyMetadata(default(Thickness), XBorderThicknessPropertyChangedCallback));

        public static DependencyProperty XMarginProperty = DependencyProperty.Register("XMargin",
            typeof(Thickness),
            typeof(Part),
            new PropertyMetadata(default(Thickness), XMarginPropertyChangedCallback));

        public static DependencyProperty XPaddingProperty = DependencyProperty.Register("XPadding",
            typeof(Thickness),
            typeof(Part),
            new PropertyMetadata(default(Thickness), XPaddingPropertyChangedCallback));

        public static DependencyProperty XIsDesignModeProperty = DependencyProperty.Register("XIsDesignMode",
            typeof(bool),
            typeof(Part),
            new PropertyMetadata(false, XIsDeisgnModePropertyChangedCallback));

        public static DependencyProperty XIsVisibleProperty = DependencyProperty.Register("XIsVisible",
            typeof(bool),
            typeof(Part),
            new PropertyMetadata(true, XIsVisiblePropertyChangedCallback));
        #endregion

        #region dependencyProperty callback
        private static void XDisplayConditionPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.RaisePropertyChanged(e.Property.Name);
        }

        private static void XLeftPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.UpdateSize();
            part.RaisePropertyChanged(e.Property.Name);
        }

        private static void XTopPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.UpdateSize();
            part.RaisePropertyChanged(e.Property.Name);
        }

        private static void XWidthPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.Width = (double)e.NewValue;
            part.NeedUpdateLayout = true;
            part.RaisePropertyChanged(e.Property.Name);
            part.Refresh();
        }

        private static void XHeightPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.Height = (double)e.NewValue;
            part.NeedUpdateLayout = true;
            part.RaisePropertyChanged(e.Property.Name);
            part.Refresh();
        }

        private static void XPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.RaisePropertyChanged(e.Property.Name);
            part.Refresh();
        }

        private static void XBorderBrushPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.RaisePropertyChanged(e.Property.Name);
            part.Refresh();
        }
        private static void XBorderThicknessPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.RaisePropertyChanged(e.Property.Name);
            part.Refresh();
        }
        private static void XMarginPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.RaisePropertyChanged(e.Property.Name);
            part.Margin = part.XMargin;
        }
        private static void XPaddingPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.RaisePropertyChanged(e.Property.Name);
            part.Refresh();
        }
        private static void XIsDeisgnModePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.RaisePropertyChanged(e.Property.Name);
        }
        private static void XIsVisiblePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UI.Part part = d as UI.Part;
            part.RaisePropertyChanged(e.Property.Name);
            if (part.XIsVisible)
            {
                part.Active(part.PartContext);
                part.Refresh();
            }
            else
            {
                part.Deactive();
            }
        }
        #endregion

    }
}
